home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / sysb091a.zip / sysbench / src / pmb_diskio.c < prev    next >
Text File  |  1996-05-27  |  10KB  |  533 lines

  1. /* diskio.c - disk benchmark
  2.  *
  3.  * Author:  Kai Uwe Rommel <rommel@ars.muc.de>
  4.  * Created: Fri Jul 08 1994
  5.  */
  6.  
  7. // modified 1994-08-10 by Henrik Harmsen
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13.  
  14. #define INCL_DOS
  15. #define INCL_DOSDEVICES
  16. #define INCL_DOSDEVIOCTL
  17. #define INCL_DOSERRORS
  18. //#define INCL_NOPM
  19. #include <os2.h>
  20.  
  21. #include "diskacc2.h"
  22.  
  23. #define INTERVAL 10
  24.  
  25. int nHandle;
  26. unsigned nSides, nTracks, nSectors;
  27. char *pBuffer;
  28.  
  29. int time_over;
  30. double dhry_time, dhry_result;
  31.  
  32. extern unsigned long Number_Of_Runs;
  33. extern long dhry_stone(void);
  34. extern void err(char* s);
  35.  
  36. int bench_dhry(void);
  37.  
  38. VOID APIENTRY timer_thread(ULONG nArg)
  39. {
  40. #if 1
  41.   HEV hSem;
  42.   HTIMER hTimer;
  43.  
  44.   DosCreateEventSem(0, &hSem, DC_SEM_SHARED, 0);
  45.   DosAsyncTimer(nArg * 1000, (HSEM) hSem, &hTimer);
  46.   DosWaitEventSem(hSem, SEM_INDEFINITE_WAIT);
  47.   DosStopTimer(hTimer);
  48.   DosCloseEventSem(hSem);
  49. #else
  50.   DosSleep(nArg * 1000);
  51. #endif
  52.  
  53.   time_over = 1;
  54.   Number_Of_Runs = 0;
  55.  
  56.   DosExit(EXIT_THREAD, 0);
  57. }
  58.  
  59. int start_alarm(ULONG nSeconds)
  60. {
  61.   TID ttid;
  62.  
  63.   time_over = 0;
  64.   Number_Of_Runs = -1;
  65.  
  66.   if (DosCreateThread(&ttid, timer_thread, nSeconds, 0, 8192))
  67.      {
  68.      err("Cannot create timer thread");
  69.      return -1;
  70.      }
  71.  
  72.   return 0;
  73. }
  74.  
  75. int start_timer(QWORD *nStart)
  76. {
  77.   if (DosTmrQueryTime(nStart))
  78.      {
  79.      err("Timer error");
  80.      return -1;
  81.      }
  82.  
  83.   return 0;
  84. }
  85.  
  86. int stop_timer(QWORD *nStart, int accuracy)
  87. {
  88.   QWORD nStop;
  89.   ULONG nFreq;
  90.  
  91.   if (DosTmrQueryTime(&nStop))
  92.      {
  93.      err("Timer error 2");
  94.      return -1;
  95.      }
  96.   if (DosTmrQueryFreq(&nFreq))
  97.      {
  98.      err("Timer error 3");
  99.      return -1;
  100.      }
  101.  
  102.   nFreq = (nFreq + accuracy / 2) / accuracy;
  103.  
  104.   return (nStop.ulLo - nStart->ulLo) / nFreq;
  105. }
  106.  
  107. int bench_transfer(int nTrack, int nDirection)
  108. {
  109.   int nCnt, nData = 0, nTime, Dxfer;
  110.   QWORD nLocal;
  111.  
  112. //printf("Data transfer rate on track %-4d: ", nTrack);
  113. //fflush(stdout);
  114.  
  115.   if (start_alarm(INTERVAL))
  116.     return -1;
  117.  
  118.   if (start_timer(&nLocal))
  119.     return -1;
  120.  
  121.   for (nCnt = 0; !time_over; nCnt++)
  122.   {
  123.     if (DskRead(nHandle, nCnt % nSides, nTrack + (nCnt / nSides) * nDirection, 1, nSectors, pBuffer))
  124.      {
  125.       err("Disk read error - bench transfer.");
  126.       return -1;
  127.       }
  128.  
  129.     nData += nSectors * 512;
  130.   }
  131.  
  132.   if ((nTime = stop_timer(&nLocal, 1024)) == -1)
  133.     return -1;
  134.  
  135.   Dxfer = nData / nTime;
  136.  
  137.   return Dxfer;
  138. }
  139.  
  140. int bench_bus(void)
  141. {
  142.   int nCnt, nData = 0, nTime, Dxfer;
  143.   QWORD nLocal;
  144.  
  145. //printf("Drive cache/bus transfer rate: ");
  146. //fflush(stdout);
  147.  
  148.   if (start_alarm(INTERVAL))
  149.     return -1;
  150.  
  151.   if (start_timer(&nLocal))
  152.     return -1;
  153.  
  154.   for (nCnt = 0; !time_over; nCnt++)
  155.   {
  156.     if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
  157.        {
  158.         err("Disk read error - bus/cache.");
  159.         return -1;
  160.         }
  161.  
  162.     nData += nSectors * 512;
  163.   }
  164.  
  165.   if ((nTime = stop_timer(&nLocal, 1024)) == -1)
  166.     return -1;
  167.  
  168.   Dxfer = nData / nTime;
  169.  
  170.   return Dxfer;
  171. }
  172.  
  173. int bench_latency(void)
  174. {
  175.   int nCnt, nSector, nTime;
  176.   QWORD nLocal;
  177.  
  178. //printf("Average latency time: ");
  179. //fflush(stdout);
  180.  
  181.   srand(1);
  182.  
  183.   if (start_alarm(INTERVAL))
  184.     return -1;
  185.  
  186.   if (start_timer(&nLocal))
  187.     return -1;
  188.  
  189.   for (nCnt = 0; !time_over; nCnt++)
  190.   {
  191.     nSector = rand() * nSectors / RAND_MAX + 1;
  192.  
  193.     if (DskRead(nHandle, 0, 0, nSector, 1, pBuffer))
  194.        {
  195.         err("Disk read error - bench latency.");
  196.         return -1;
  197.         }
  198.   }
  199.  
  200.   if ((nTime = stop_timer(&nLocal, 1000)) == -1)
  201.     return -1;
  202.  
  203.   nTime = nTime * 10 / nCnt;
  204.  
  205. //printf("%d.%d ms\n", nTime / 10, nTime % 10);
  206.  
  207.   return nTime;
  208. }
  209.  
  210. int bench_seek(void)
  211. {
  212.   int nCnt, nTrack, nTime;
  213.   QWORD nLocal;
  214.  
  215. //printf("Average data access time: ");
  216. //fflush(stdout);
  217.  
  218.   srand(1);
  219.  
  220.   if (start_alarm(INTERVAL))
  221.     return -1;
  222.  
  223.   if (start_timer(&nLocal))
  224.     return -1;
  225.  
  226.   for (nCnt = 0; !time_over; nCnt++)
  227.   {
  228.     nTrack = rand() * nTracks / RAND_MAX;
  229.  
  230.     if (DskRead(nHandle, 0, nTrack, 1, 1, pBuffer))
  231.        {
  232.         err("Disk read error - bench seek.");
  233.         return -1;
  234.         }
  235.   }
  236.  
  237.   if ((nTime = stop_timer(&nLocal, 1000)) == -1)
  238.     return -1;
  239.  
  240.   nTime = nTime * 10 / nCnt;
  241.  
  242. //printf("%d.%d ms\n", nTime / 10, nTime % 10);
  243.  
  244.   return nTime;
  245. }
  246.  
  247. VOID APIENTRY dhry_thread(ULONG nArg)
  248. {
  249.   APIRET rc;
  250.  
  251.   rc = DosSetPriority(PRTYS_THREAD, PRTYC_IDLETIME, PRTYD_MAXIMUM, 0);
  252.  
  253.   dhry_time = dhry_stone();
  254.  
  255.   DosExit(EXIT_THREAD, 0);
  256. }
  257.  
  258.  
  259. double bench_concurrent(void)
  260. {
  261.   int nCnt, nData = 0, nTime;
  262.   double percent;
  263.   QWORD nLocal;
  264.   TID dtid;
  265.   APIRET rc;
  266.  
  267.   if (start_alarm(INTERVAL))
  268.     return -1;
  269.  
  270.   if (DosCreateThread(&dtid, dhry_thread, 0, 0, 8192))
  271.     return -1;
  272.  
  273.   if (start_timer(&nLocal))
  274.     return -1;
  275.  
  276.   for (nCnt = 0; !time_over; nCnt++)
  277.   {
  278.     if (DskRead(nHandle, 0, 0, 1, nSectors, pBuffer))
  279.        {
  280.         err("Disk read error - concurrency test.");
  281.         return -1;
  282.         }
  283.  
  284.     nData += nSectors * 512;
  285.   }
  286.  
  287.   if ((nTime = stop_timer(&nLocal, 1024)) == -1)
  288.     return -1;
  289.  
  290.   if ((rc = DosWaitThread(&dtid, DCWW_WAIT)) && rc != ERROR_INVALID_THREADID)
  291.     return -1;                             /* it may have already terminated */
  292.  
  293.   dhry_time = (dhry_time + 500) / 1000;
  294.  
  295.   percent = ((dhry_result-(Number_Of_Runs / dhry_time)) * 100 / dhry_result);
  296.  
  297.   return percent;
  298. }
  299.  
  300. int bench_disk(int nDisk)
  301. {
  302.   char szName[8];
  303.  
  304.   sprintf(szName, "$%d:", nDisk);
  305.  
  306.   if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
  307.      {
  308.       err("Cannot access disk");
  309.       return -1;
  310.       }
  311.  
  312. //  printf("\nDisk %d: %d sides, %d cylinders, %d sectors per track = %d MB\n", nDisk, nSides, nTracks, nSectors, nSides * nTracks * nSectors / 2048);
  313.  
  314.   if ((pBuffer = malloc(nSectors * 512)) == NULL)
  315.      {
  316.       err("Not enough memory - bench disk.");
  317.       return -1;
  318.       }
  319.  
  320.   bench_bus();
  321.   bench_transfer(0, 1);
  322.   bench_transfer(nTracks - 1, -1);
  323. //  bench_concurrent();
  324.   bench_latency();
  325.   bench_seek();
  326.  
  327.   free(pBuffer);
  328.   DskClose(nHandle);
  329.  
  330.   return 0;
  331. }
  332.  
  333. static double bench_disk_avseek(int nDisk)
  334. {
  335.   char szName[8];
  336.   double r;
  337.  
  338.   sprintf(szName, "$%d:", nDisk);
  339.  
  340.   if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
  341.     err("Disk IO test error : Cannot access disk - avseek.");
  342.     exit(1);
  343.   }
  344.  
  345.   if ((pBuffer = malloc(nSectors * 512)) == NULL) {
  346.     err("Disk IO test error : malloc() failed.");
  347.     exit(1);
  348.   }
  349.  
  350.   r = bench_seek();
  351.  
  352.   free(pBuffer);
  353.   DskClose(nHandle);
  354.  
  355.   return r;
  356. }
  357.  
  358. static double bench_disk_transfer(int nDisk)
  359. {
  360.   char szName[8];
  361.   double r;
  362.  
  363.   sprintf(szName, "$%d:", nDisk);
  364.  
  365.   if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0) {
  366.     err("Disk IO test error : Cannot access disk - bench disk xfer.");
  367.     exit(1);
  368.   }
  369.  
  370.   if ((pBuffer = malloc(nSectors * 512)) == NULL) {
  371.     err("Disk IO test error : malloc() failed.");
  372.     exit(1);
  373.   }
  374.  
  375.   r = (bench_transfer(nTracks-1, -1)+bench_transfer(0, 1)+bench_transfer(nTracks/2, 1))/3;
  376.  
  377.   free(pBuffer);
  378.   DskClose(nHandle);
  379.  
  380.   return r;
  381. }
  382.  
  383.  
  384. double pmb_diskio_avseek(int disknr)
  385. {
  386.   double r;
  387.  
  388.   disknr++;
  389.  
  390. //  DosCreateEventSem(NULL, &hSemTimer, DC_SEM_SHARED, 0);
  391. //  DosSleep(500);
  392.  
  393.   r = bench_disk_avseek(disknr);
  394.  
  395. //  DosCloseEventSem(hSemTimer);
  396. //  hSemTimer = 0;
  397.   return r;
  398. }
  399.  
  400. double pmb_buscache_xfer(int disknr)
  401. {
  402.   double r;
  403.   char szName[8];
  404.  
  405.   disknr++;
  406.  
  407.   sprintf(szName, "$%d:", disknr);
  408.  
  409.   if ((nHandle = DskOpen(szName, 0, 0, &nSides, &nTracks, &nSectors)) < 0)
  410.      {
  411.       err("Cannot access disk");
  412.       return -1;
  413.       }
  414.  
  415.   if ((pBuffer = malloc(nSectors * 512)) == NULL)
  416.      {
  417.       err("Not enough memory - bus cache test.");
  418.       return -1;
  419.       }
  420.  
  421.   r = bench_bus();
  422.  
  423.   free(pBuffer);
  424.   DskClose(nHandle);
  425.   return r;
  426. }
  427.  
  428. double pmb_diskio_transfer(int disknr)
  429. {
  430.   double r;
  431.  
  432.   disknr++;
  433.   r = bench_disk_transfer(disknr);
  434.  
  435.   return r;
  436. }
  437.  
  438. double